package com.xiyuan.smartutils.control;

import com.xiyuan.smartutils.DateTimes;
import com.xiyuan.smartutils.logging.LogFactory;
import com.xiyuan.smartutils.logging.Logger;
import com.xiyuan.smartutils.seqs.Sequence;

/**
 * 线程操作者
 *
 * @version v1.0.0 @author lgz 2017-8-27 新建与整理
 */
public class Threader extends Threadx {
    private static final Logger log = LogFactory.getLogger(Threader.class);
    private static final Sequence sequence = new Sequence();
    
    private final ThreaderController controller;
    
    //线程活动状态
    private volatile boolean idle = true;
    private volatile long idleTimeMs = System.currentTimeMillis();
    
    private long seq;
    
    public Threader(ThreaderController controller) {
        this.controller = controller;
        this.seq = sequence.next();
    }
    
    /**************************************************************************************/
    //线程组&线程名&线程回调循环操作
    
    /**************************************************************************************/
    
    @Override
    public String getThreadName() {
        return controller.getThreadName() + "-" + this.seq;
    }
    
    @Override
    protected ThreadGroup getThreadGroup() {
        return controller.getThreadGroup();
    }
    
    @Override
    protected void loop() {
        Runnable command = controller.accept();
        if (command == null) {return;}
        
        try {
            idle = false;
            controller.active();
            command.run();
        }
        catch (Throwable e) {
            log.error(String.format("线程池处理时异常：[%s]", e.getMessage()), e);
        }
        finally {
            idle = true;
            idleTimeMs = System.currentTimeMillis();
            controller.idle();
            command = null;
        }
    }
    
    /**************************************************************************************/
    //获取运行时属性
    
    /**************************************************************************************/
    
    public boolean isActive() {
        return !idle;
    }
    
    public boolean isIdle() {
        return idle;
    }
    
    public long getIdleTimeMs() {
        return idleTimeMs;
    }
    
    public String getIdleTimeString() {
        return DateTimes.toDateTimeString(idleTimeMs);
    }
    
    public boolean isIdleTimeout(long maxIdleTimeMs) {
        return idle && (System.currentTimeMillis() - idleTimeMs - maxIdleTimeMs) > 0;
    }
}
